<?php

abstract class FP_Application {

    /*
     * Set a registry variable
     * @param string $pKey Name of variable
     * @param mixed $pVal value of variable
     */
    public static function Set($pKey, $pVal){
	Zend_Registry::set($pKey, $pVal);
    }

    /*
     * Get a registry variable
     * @param string $pKey Name of variable
     * @return mixed Stored variable
     */
    public static function Get($pKey){

	if (Zend_Registry::isRegistered($pKey))
	    return Zend_Registry::get($pKey);
	return null;
    }

    public static function getStagingEnvironment(){

	return FP_Application_Bootstrap::GetStagingEnvironment();
    }

    public static function getNamespace(){
	return APPLICATION_NAMESPACE;
    }

    public static function getConfig(){

	return Zend_Registry::get('config');

    }

    public static function getControllerNames(){

	$controller_path = BASE_DIR . 'app/controllers';

	$controller_dir = opendir($controller_path);

	$controllers = array();

	while ($entry = readdir($controller_dir)){

	    if (preg_match('/^\w+\.php$/i', $entry)){
 		require_once("{$controller_path}/{$entry}");
		$f = new Zend_Reflection_File("{$controller_path}/{$entry}");
		$classes = $f->getClasses();

		foreach ($classes as $class){

		    $interfaces = $class->getInterfaces();

		    foreach ($interfaces as $interface){

			if ($interface->getName() == 'FP_Controller_Action_Interface')
			    $controllers[] = $class->getName();

		    }

		}

	    }

	}

	return $controllers;
    }

    public static function getViewEngine(){
	return FP_Application_Subsystem_View::$view;
    }

    public static function getLogger(){
	if (FP_Application_Subsystem_Logger::$enable)
	    return FP_Application_Subsystem_Logger::$logger;
	else
	    return null;

    }

    public static function getCache($pCache='core'){
	if (FP_Application_Subsystem_Cache::$enabled)
	    return FP_Application_Subsystem_Cache::$manager->getCache($pCache);
	else
	    return null;
    }

    public static function getSession(){

	return FP_Application_Subsystem_Session::$session;

    }

    public static function getAcl(){
	if (FP_Application_Subsystem_Acl::$enabled)
	    return FP_Application_Subsystem_Acl::GetAcl();
	else
	    return null;

    }

    public static function classFactory($pClassSuffix){
	$Class = self::getNamespace() . '_' . $pClassSuffix;
	return new $Class();
    }

    public static function Translate($pString){
	return Zend_Registry::get('Zend_Translate')->translate($pString);
    }

    public static function DeAuthenticate(){

	Zend_Auth::getInstance()->clearIdentity();

    }

    public static function AdapterAuthenticate($pAdapter, $pCallback=null){
	$auth    = Zend_Auth::getInstance();

	$result  = $auth->authenticate($pAdapter);

	if ($result->isValid()){
	    $user = self::GetIdentity();
	    $user->postLogin();

	    if ($pCallback)
		call_user_func($pCallback);

	    return true;
	}

	return false;
    }

    public static function PasswordAuthenticate($pUsername, $pPassword, $pCallback=null){

	$auth    = Zend_Auth::getInstance();

	$adapter = new FP_Auth_Adapter($pUsername, $pPassword);

	$result  = $auth->authenticate($adapter);
	if ($result->isValid()){
	    $user = self::GetIdentity();
	    $user->postLogin();

	    if ($pCallback)
		call_user_func($pCallback);

	    return true;
	}

	return false;
    }

    public static function CookieAuthenticate(){

	if (array_key_exists('silk_uid', $_COOKIE)){
	    $auth    = Zend_Auth::getInstance();
	    $adapter = new FP_Auth_Cookie_Adapter($_COOKIE['silk_uid']);
	    $result = $auth->authenticate($adapter);
	    if ($result->isValid()){
		$user = self::GetIdentity();
		$user->postLogin();
		return true;
	    }

	}

	return false;

    }

    public static function ForceAuthenticate(FP_User $pUser){

	$auth    = Zend_Auth::getInstance();
	$adapter = new FP_Auth_Auto_Adapter($pUser);
	$result  = $auth->authenticate($adapter);
	if ($result->isValid()){
	    $user = self::GetIdentity();
	    $user->postLogin();
	    return true;
	}

	return false;
    }

    public static function HasIdentity(){

	return Zend_Auth::getInstance()->hasIdentity();

    }

    public static function &GetIdentity(){

	$auth = Zend_Auth::getInstance();
	if ($auth->hasIdentity())
	    $identity = $auth->getIdentity();
	else
	    $identity = null;

	return $identity;

    }

    public static function EncryptPassword($pPassword){

	return md5($pPassword);

    }

    public static function MakePlural($pString){
	if (preg_match("/({$pString})y$/", $pString,$matches)){
	    return $matches[1] . 'ies';
	} else
	    return $pString . 's';
    }

    public static function PermissionExists($pPermission){
	$Permissions = self::classFactory('Permissions');

	if (is_array($pPermission)){
	    $resource  = $pPermission['resource'];
	    $privilege = $pPermission['privilege'];
	} else if ($pPermission instanceof FP_Permission){
	    $resource  = $pPermission->resource;
	    $privilege = $pPermission->privilege;
	} else {

	    $permission = $Permissions->fetchByName($pPermission, true);
	    if ($permission){
		$resource  = $permission->resource;
		$privilege = $permission->privilege;
	    } else {
		$permissions = array();
		include(BASE_DIR . 'config/permissions.php');
		if (array_key_exists($pPermission, $permissions)){
		    $resource = $permissions[$pPermission]['resource'];
		    $privilege = $permissions[$pPermission]['privilege'];
		} else
		    return false;
	    }
	}

	return ($Permissions->count(array('resource' => $resource, 'privilege' => $privilege)) > 0);
    }

    public static function HasPermission($pPermission, $pUser=null){
	$session = FP_Application::getSession();
	$acl     = FP_Application::getAcl();

	$Permissions = self::classFactory('Permissions');

	if (is_array($pPermission)){
	    $resource  = $pPermission['resource'];
	    $privilege = $pPermission['privilege'];
	} else if ($pPermission instanceof FP_Permission){
	    $resource  = $pPermission->resource;
	    $privilege = $pPermission->privilege;
	} else {

	    $permission = $Permissions->fetchByName($pPermission, true);
	    if ($permission){
		$resource  = $permission->resource;
		$privilege = $permission->privilege;
	    } else {
		$permissions = array();
		include(BASE_DIR . 'config/permissions.php');
		if (array_key_exists($pPermission, $permissions)){
		    $resource = $permissions[$pPermission]['resource'];
		    $privilege = $permissions[$pPermission]['privilege'];
		} else
		    return false;
	    }
	}

	try {
	    if (!FP_Application::hasIdentity()){
		return $acl->isAllowed('role-guest', $resource, $privilege);
	    } else {
		$user = ($pUser) ? $pUser : FP_Application::getIdentity();
		return $acl->isAllowed($user, $resource, $privilege);
	    }
	} catch (Zend_Acl_Exception $x){
	    return false;
	}
    }

    public static function CreatePermission($pName, $pResource, $pPrivilege, $pRoles){

	$Permissions = FP_Application::classFactory('Permissions');
	$permission = $Permissions->create(
			    array(
				'name'      => $pName,
				'resource'  => $pResource,
				'privilege' => $pPrivilege
			    ), true
			);

	$roles = array();

	$Roles = FP_Application::classFactory('Roles');
	$Users = FP_Application::classFactory('Users');

	if (is_array($pRoles)){
	    foreach ($pRoles as $role){
		if ($role instanceof FP_Role)
		    $Roles->addPermissionToRole($role, $permission);
		else if ($role instanceof FP_User)
		    $Users->addPermissionToUser($role, $permission);
		else {
		    $Roles = self::classFactory('Roles');
		    $_role = $Roles->getModelObject($role);
		    if ($_role)
			$Roles->addPermissionToRole($_role, $permission);
		    else
			logwarn('FP_Application.CreatePermission: Unrecognized acl role - ' . $role);
		}
	    }
	}

    }

    protected static function getBrowserObject(){
	$browser = self::get('browser');
	if ($browser === null){
	    $browser = new Browser();
	    self::set('browser', $browser);
	}
	return $browser;
    }

    public static function getBrowserName(){
	$browser = self::getBrowserObject();
	return $browser->getBrowser();
    }

    public static function getBrowserVersion(){
	$browser = self::getBrowserObject();
	return $browser->getVersion();
    }

    public static function isBrowserMobile(){
	$browser = self::getBrowserObject();
	return $browser->isMobile();
    }

    public static function getBrowserPlatform(){
	$browser = self::getBrowserObject();
	return $browser->getPlatform();
    }

    public static function debug($pMessage){
	logdebug($pMessage);
    }

    public static function info($pMessage){
	loginfo($pMessage);
    }

    public static function warn($pMessage){
	logwarn($pMessage);
    }

    public static function err($pMessage){
	logerr($pMessage);
    }

}

?>